package yuan.plugins.banBreak;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;

import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;

import lombok.Getter;
import lombok.val;

/**
 * 主类
 *
 * @author yuanlu
 *
 */
public class Main extends JavaPlugin implements Listener {

	/** 插件名称 用于信息提示 模板自动生成 */
	public final static String		SHOW_NAME	= "元路禁止破坏";

	/** 插件主体 */
	private static @Getter Main		main;

	/** 调试模式 */
	private static @Getter boolean	DEBUG;
	/** 强制替换文件 */
	private static @Getter boolean	FORECE_OUT_FILE;

	/**
	 * BUKKIT事件
	 *
	 * @param e event
	 * @deprecated BUKKIT CALL
	 */
	@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
	@Deprecated
	public static final void onBreak(BlockBreakEvent e) {
		val	block	= e.getBlock();
		val	player	= e.getPlayer();
		if (block == null || player == null) return;
		val	type	= block.getType();
		val	conf	= Conf.get(type);
		if (conf == null) return;

		if (conf.cancelBreak(player, type)) e.setCancelled(true);
		else e.setDropItems(false);
	}

	/**
	 * BUKKIT事件
	 *
	 * @param e event
	 * @deprecated BUKKIT CALL
	 */
	@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
	@Deprecated
	public static final void onBreak(PlayerQuitEvent e) {
		Conf.clear(e.getPlayer().getUniqueId());
	}

	/** 插件配置文件 */
	private @Getter FileConfiguration config;

	/**
	 * bstats数据收集<br>
	 * 在{@link #onEnable()}调用
	 */
	private void bstats() {

		// 注册bstats
		Metrics metrics = new Metrics(this, 13513);
		metrics.addCustomChart(new SimplePie("pls_count", () -> {
			int count = 0;
			for (Plugin pl : getServer().getPluginManager().getPlugins()) {
				if (pl.getName().startsWith("yuanlu")) count++;
			}
			return Integer.toString(count);
		}));

	}

	/** 检查中央配置文件 */
	private void checkYuanluConfig() {
		val	yuanluFolder	= new File(getDataFolder().getParentFile(), "yuanlu");
		val	configFile		= new File(yuanluFolder, "config.yml");
		if (!configFile.exists()) {
			DEBUG			= false;
			FORECE_OUT_FILE	= false;
		} else {
			YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
			DEBUG			= config.getBoolean("debug", false);
			FORECE_OUT_FILE	= config.getBoolean("force-override-file", false);
		}
	}

	/**
	 * 加载配置
	 *
	 * @param fileName 配置文件名，例如{@code "config.yml"}
	 * @return 配置文件
	 */
	public YamlConfiguration loadFile(String fileName) {
		File file = new File(getDataFolder(), fileName);
		if (FORECE_OUT_FILE || !file.exists()) try {
			if (FORECE_OUT_FILE) file.delete();
			saveResource(fileName, false);
		} catch (IllegalArgumentException e) {
			try {
				file.createNewFile();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		} catch (Exception e1) {
			e1.printStackTrace();
			return null;
		}
		try {
			return YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file), "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public void onDisable() {
		// 关闭插件时自动发出
		getLogger().info("§a" + SHOW_NAME + "-关闭");
	}

	@Override
	public void onEnable() {
		checkYuanluConfig();
		bstats();

		// 启用插件时自动发出
		main = this;
		getLogger().info("§a" + SHOW_NAME + "-启动");
		config = loadFile("config.yml");
		Conf.init();
		getServer().getPluginManager().registerEvents(this, this); // 注册监听器
	}

	/**
	 * 保存配置
	 *
	 * @param c        配置文件
	 * @param fileName 保存名称
	 * @author yuanlu
	 */
	public void saveFile(FileConfiguration c, String fileName) {
		val f = new File(getDataFolder(), fileName);
		try (val o = new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8)) {
			o.write(c.saveToString());
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
}
